package com.kgis.map.layer.ogc {

   import com.kgis.map.geometry.basetype.Extent;
   import com.kgis.map.geometry.basetype.Pixel;
   import com.kgis.map.geometry.basetype.Size;
   import com.kgis.map.layer.Grid;
   import com.kgis.map.layer.Layer;
   import com.kgis.map.layer.params.ogc.WMSParams;
   import com.kgis.map.projection.Projection;
   import com.kgis.map.tile.ImageTile;

   /**
    * Instances of WMS are used to display data from OGC Web Mapping Services.
    */
   public class WMS extends Grid {

      private var _reproject:Boolean = false;

      public function WMS(id:int, name:String = "", url:String = "", layers:String = "") {

         super(id, name, url, new WMSParams(layers));

         this.singleTile = true;

         CACHE_SIZE = 32;

      }

      public function get maxExtent():Extent {
         if (!this.map.maxExtent)
            return null;

         var maxExtent:Extent = this.map.maxExtent.clone();
         if (this.map != true && this._reproject == true && projection.srsCode != this.map.projection.srsCode) {
            maxExtent.transform(this.projection, this.map.projection);
         }

         return maxExtent;
      }

      override public function getURL(bounds:Extent):String {
         var projection:Projection = this.projection;
         var projectedBounds:Extent = bounds.clone();

         if (this.map != true && this._reproject == true && projection.srsCode != this.map.projection.srsCode) {
            projectedBounds.transform(this.map.projection.clone(), projection.clone());
         }

         this.params.bbox = projectedBounds.boundsToString();
         (this.params as WMSParams).width = this.imageSize.w;
         (this.params as WMSParams).height = this.imageSize.h;
         if (this._reproject == false) {
            if (projection != null || this.map.projection != null)
               (this.params as WMSParams).srs = (projection == null) ? this.map.projection.srsCode : projection.srsCode;
         }
         else {
            (this.params as WMSParams).srs = projection.srsCode;
         }
         var requestString:String;
         if (this.url.indexOf("?") == -1)
            requestString = this.url + "?" + this.params.toGETString();
         else
            requestString = this.url + "&" + this.params.toGETString();

         return requestString;
      }

      override public function addTile(bounds:Extent, position:Pixel):ImageTile {
         var url:String = this.getURL(bounds);
         var img:ImageTile = new ImageTile(this, position, bounds, url, new Size(this.tileWidth, this.tileHeight));
         if (this.method != null)
            img.method = this.method;
         return img;
      }

      public function get reproject():Boolean {
         return this._reproject;
      }

      public function set reproject(value:Boolean):void {
         this._reproject = value;
      }

      public function get exception():String {
         return (this.params as WMSParams).exceptions;
      }

      public function set exception(value:String):void {
         (this.params as WMSParams).exceptions = value;
      }

      override public function clone():Layer{
         var wms:WMS = new WMS(this.id,this.name,this.url);
         return wms;
      }

   }
}

